/*-------------------------------------------------------------------------------
* file:     app_key.c
* brief:    application
* copyright Copyright (C) 2020-2022 @ NanoIC
* Date:     2022-08-15
* Version:  V1.00
* Author:   JMH
*-------------------------------------------------------------------------------*/

/* Includes ---------------------------------------------------------------*/
#include "app_key.h" 
#include "app_parameter.h"
volatile uint8_t win_flag = 0;

/* externs function--------------------------------------------------------*/
extern unsigned int *chip_get_pin_name_addr(pin_name_e ePinName);
extern uint8_t one_wire_bus_app_sleep_or_wakeup_flag;
extern bool one_wrie_bus_app_rec_flash_log_cmd(SourcePacketStr *p_rec_packet);
extern volatile bool global_15s_sleep_exit_flag; 

void app_key_all_tick_sync(void);
/* Private variablesr------------------------------------------------------*/
//矩阵键盘键值表
/* Private variablesr------------------------------------------------------*/
//矩阵键盘键值表
//static const uint8_t key_map[KEY_ROW_NUMBER][KEY_COLUME_NUMBER] = {
//	
//{0,			KB_Enter,	KB_yinhao,	KB_Rguohao,	KB_Back,	0,			KB_denghao,	0},\
//
//{0,			KB_N,		KB_LCtrl,	0,			KB_H,		0,			KB_Y,		KB_6},\
//
//{0,			0,			KB_C,		KB_D,		0,			KB_E,		KB_3,		0},\
//
//{KB_4,		KB_Down,	KB_xiegang,	KB_juhao,	KB_L,		KB_O,		KB_9,		0},\
//
//
//{KB_wenhao,	KB_Right,	KB_fenhao,	KB_Lguohao,	KB_P,		KB_jianhao,	KB_0,		KB_Space},\
//
//{0,			KB_B,		0,			KB_G,		0,			KB_T,		KB_5,		0},\
//
//{T_FN,		KB_LShift,	KB_V,		KB_Voice,	KB_F,		0,			KB_R,		KB_RShift},\
//
//{0,			KB_Up,		KB_RAlt,	KB_douhao,	KB_K,		KB_I,		KB_8,		0},\
//
//{KB_LAlt,	KB_Left,	KB_M,		KB_J,		KB_Win,		KB_U,		KB_7,		0},\
//
//{KB_K45,	KB_Esc,		KB_X,		KB_S,		KB_W,		KB_2,		0,			0},\
//
//{KB_Z,		KB_A,		KB_Caps,	KB_Q,		KB_Tab,		KB_1,		0,			0},\
//
//};


/* Private variablesr------------------------------------------------------*/
//矩阵键盘键值表
static const uint8_t key_map[KEY_ROW_NUMBER][KEY_COLUME_NUMBER] = {
	
{0,			KB_Enter,	KB_yinhao,	KB_Rguohao,	KB_Back,	0,			KB_denghao,	0},\

{0,			KB_N,		KB_LCtrl,	0,			KB_H,		0,			KB_Y,		KB_6},\

{0,			KB_Up,		KB_RAlt,	KB_douhao,	KB_K,		KB_I,		KB_8,		0},\

{KB_4,		KB_Down,	KB_xiegang,	KB_juhao,	KB_L,		KB_O,		KB_9,		0},\


{KB_wenhao,	KB_Right,	KB_fenhao,	KB_Lguohao,	KB_P,		KB_jianhao,	KB_0,		KB_Space},\

{0,			KB_B,		0,			KB_G,		0,			KB_T,		KB_5,		0},\

{T_FN,		KB_LShift,	KB_V,		KB_Voice,	KB_F,		0,			KB_R,		KB_RShift},\

{KB_K45,	KB_Esc,		KB_X,		KB_S,		KB_W,		KB_2,		0,			0},\

{KB_LAlt,	KB_Left,	KB_M,		KB_J,		KB_Win,		KB_U,		KB_7,		0},\

{0,			0,			KB_C,		KB_D,		0,			KB_E,		KB_3,		0},\

{KB_Z,		KB_A,		KB_Caps,	KB_Q,		KB_Tab,		KB_1,		0,			0},\

};

//按键扫描时间标志
volatile uint8_t global_key_timer_flag;
//按键扫描tick
uint16_t global_key_timer_tick;
volatile uint8_t global_key_power_on_flag;

//停止按键扫描
// volatile bool global_keyboard_stop_scan_flag;
/***************************LED*********************************/
//bit0 - bit3 依次 CapsLock、 NumLock、 Mute、 Micmute 开关标志
volatile uint8_t key_caps_etc_led_sta;
//按键使能标志、案件使能设置
volatile uint8_t keyboard_enable_flag;
volatile uint8_t keyboard_led_status;

/****************************BUTTON****************************/
//上次按键类型
ENUM_KEY_TYPE key_type_back;
ENUM_KEY_TYPE key_madia_type_back;
//普通按键发送标志
volatile uint8_t global_key_rec_ack_flag;
//多媒体按键发送标志
volatile uint8_t global_media_rec_ack_flag;
//确保多媒体按键能正常抬起
uint8_t global_madia_tick;
//按下发送计数
uint8_t global_key_btton_tick;
//按下发送计数
uint8_t global_key_btton_madia_tick;
//按键状态结构体
volatile Button_Typedef kb_btn[KEY_BOTTON_MAX_NUM];
Button_Queue_typedef key_value_queue;
//扫描出键值的存储缓冲区
volatile uint8_t key_scan_value[KEY_ROW_NUMBER];
volatile uint8_t global_key_number;
uint8_t Waiting_sleep = 0; //收到休眠指令同时有按键按下
// volatile bool global_in_sleep_p = false;

/****************************BUTTON****************************/
//按键行列
static const uint8_t global_key_pin_row_buf[KEY_ROW_NUMBER] = {
   ROW0, ROW1,ROW2,ROW3,ROW4,ROW5,ROW6,ROW7,ROW8,ROW9,ROW10
};


static const uint8_t global_key_pin_colume_buf[KEY_COLUME_NUMBER] = {
    COLUME0,COLUME1,COLUME2,COLUME3,COLUME4,COLUME5,COLUME6,COLUME7
};
//按键行
volatile uint8_t* key_pin_row_tab = NULL;
//按键列
volatile uint8_t* key_pin_colume_tab = NULL;
//LED适配
static const KEY_LED_EVT led_evt[2] = {
    {PA02,PA02_OUTPUT,PA02_GPD}, //caps
    {PA01,PA01_OUTPUT,PA01_GPD},
};

//LED适配结构体
volatile KEY_LED_VER hardware = NULL;

/***************************鬼键******************************/
#define MAX_GHOST_LINE_NEM      3
#define MAX_BIT_GHOST_NUM       6
uint16_t btn_ghost_index[MAX_BIT_GHOST_NUM];
uint8_t key_ghost_value[MAX_GHOST_LINE_NEM][3];

/* externs variablesr------------------------------------------------------*/

/* Private function--------------------------------------------------------*/
/**
 * @brief ：定时器调用的键盘扫描相关函数,0.1mS调一次
 * 
 * @param
 * @return
 */
void app_key_timer_tick_0_1ms_callback(void)
{
    global_key_timer_tick ++;
    if(global_key_timer_tick >= (KEY_SCAN_TIMER_N))
    {
        global_key_timer_tick = 0;
    }
    if(global_key_timer_tick == (KEY_SCAN_TIMER_N - 1))
    {
        global_key_timer_flag = 1;
    }
}

/**
 * @brief 适配硬件io
 * 
 */
void app_keyboard_hardware_set(void)
{

        hardware = (KEY_LED_VER)led_evt;
        key_pin_row_tab = (uint8_t *)&global_key_pin_row_buf[0];
        key_pin_colume_tab = (uint8_t *)&global_key_pin_colume_buf[0];
        #if APP_DEBUG_POWER_ON_LOG_ENABLE
            printf("DVT version\n");
        #endif
 
}

/**
 * @brief 按键io初始化
 * 
 */
void app_key_io_init(void)
{
 
    app_key_all_row_input_pull_up();
    app_key_all_colume_input_pull_up();
	app_keyboard_hardware_set(); 
}

/**
 * @brief ：按键初始化函数
 * 
 * @param
 * @return
 */
void app_key_init(bool f_power_on)
{
    app_key_io_init();
    app_key_led_io_set_init();


    global_key_timer_tick = 0x00;
    global_key_timer_flag = 0x00;
    global_key_btton_tick = 0x00;
    global_key_btton_madia_tick = 0x00;
    global_madia_tick = 0x00;
    global_key_number = 0x00;
    // global_keyboard_stop_scan_flag = false;

    if(!f_power_on)
        return;
		
	key_type_back = KEY_TYPE_FREE;
    key_madia_type_back = KEY_TYPE_FREE;
    app_key_create_queue(&key_value_queue);
    global_key_power_on_flag = 0x00;
    //keyboard_led_status=0;
    keyboard_enable_flag = 0x01;
}

//--------------------------------------------------------------------------------------------//
//-----------------------------------------LED 控制-------------------------------------------//
//--------------------------------------------------------------------------------------------//
void app_key_led_io_set_init(void)
{
    //caps
    csi_pin_set_mux(hardware[0].IO_name , hardware[0].IO_mode_output);
    // csi_pin_pull_mode(hardware[0].IO_name,GPIO_PULLDOWN);
        csi_pin_set_low(hardware[0].IO_name);
   
    //静音
    csi_pin_set_mux(hardware[1].IO_name , hardware[1].IO_mode_output);
    // csi_pin_pull_mode(hardware[1].IO_name,GPIO_PULLDOWN);
     csi_pin_set_low(hardware[1].IO_name);
}

/**
 * @brief led控制函数
 * 
 * @param LED 选择led
 * @param on 是否打开
 */
void app_key_led_set_mode(LED_STATUS LED, uint8_t on)
{
    pin_name_e ePinName   = 0;
    switch(LED)
    {
        case LED_CAPS: 
            ePinName   = hardware[0].IO_name;
            break;
        case LED_MIC: 
            ePinName   = hardware[1].IO_name;
            break;
        default: 
            break;
    }
    if(on == 0x01)
    {
        // 开灯
        csi_pin_set_high(ePinName);
        

    }else if(on == 0x00)
    {
        // 关闭
        csi_pin_set_low(ePinName);

    }
}
/**
 * @brief : 有多键按下时，将所有Tick同步到最小值
 * @return */
uint8_t app_key_waiting_sleep_process(void)
{
    if(global_key_number != 0x00)
    {
        //有按键
        Waiting_sleep = 0x01;
    }else
    {
        Waiting_sleep = 0x00;
    }
    return Waiting_sleep;
}

//--------------------------------------------------------------------------------------------//
//-----------------------------------------按键进程-------------------------------------------//
//--------------------------------------------------------------------------------------------//
/**
 * @brief : 键盘处理进程,键扫描时间2mS
 * 
 */
void app_key_process(void)
{
    //上电先发心跳包机制
    if(global_key_power_on_flag < 1||ota_first_flag)
        return;
    if(!global_key_timer_flag)
        return;						//心跳节奏
    global_key_timer_flag = 0x00;
    uint8_t key_number = 0,alls;
    bool f_need_send;


//	if(one_wire_bus_app_sleep_or_wakeup_flag)
//	{
//		return;
//	}
    key_number = app_key_scan(); //按键扫描

	if(kb_lock_state)
	{
		if(!pad_cover_state && !pad_lcd_state)
		{
			if(key_number)
			{
//				get_kb_lock_flag=0;
				global_gsensor_send=true;	
			}		
		}		
					
		for(uint8_t i=0;i<KEY_ROW_NUMBER;i++)
		{
			key_scan_value[i] = 0;
		}
		key_number=0;
	}
	else
	{
		if(global_weakup_flag)
		{
			if(key_number==0&&get_kb_lock_flag==2)
			{
				uint8_t key_buf[6]={0};
				key_buf[0]=0x3a;
				one_wire_bus_app_send_keyboard(0,(uint8_t *)&key_buf[0],1);
				get_kb_lock_flag=3;
			}else if(key_number==0 && get_kb_lock_flag==3){
				
				uint8_t key_buf[6]={0};
				one_wire_bus_app_send_keyboard(0,(uint8_t *)&key_buf[0],0);
				get_kb_lock_flag=1;
				global_weakup_flag=false;
			}
		}
		
	}
	
	
	//拉低row引脚
	app_key_all_row_out_low();
    
    app_key_get_botton_to_queue(key_number);   //添加队列

    global_key_number = key_number;  
	

    if(app_key_check_ghost(&key_value_queue,key_number) > 0x00) //没有鬼键则判断成立，提出鬼键
    {
        /* 
        * 1、有按键按下状态
        * 2、根据键盘切换状态
        * 3、上报唤醒包
        */

        app_sleep_timer_clear();
        global_upgrade_stop_herat_flag = 0x01;
		flash_log_flag=0;
		flash_log_tiner_tick=0;
		
    }else
    {
        //无按键按下
    }

    f_need_send = false;
    alls = 0x00;
    for(uint8_t i = 0; i < KEY_BOTTON_MAX_NUM; i++)
    {
        uint8_t status;

        bool f_press = app_key_have_press_status(&key_value_queue,i); //检查案件状态

        if(f_press)
        {
            status = app_key_tick_change(&key_value_queue,i,0x01); //按键按下计时
        }else
        {
            status = app_key_tick_change(&key_value_queue,i,0x00);
        }
        if(status == 1)     //确定要发的
        { 
            f_need_send = true;
            alls = 0x01;
        }
        if(status == 2)     //防止重发
        {
            f_need_send = true;   //条件判断要发的
            if(alls == 0x00)
            {
                alls = 0x02;
            }
        }
    }
    app_key_all_tick_sync();
    if(f_need_send == true)
    {
		if(one_wire_bus_app_sleep_or_wakeup_flag == 0x01)
        {
            one_wire_bus_app_sleep_or_wakeup_flag = 0x00;
//			if(global_15s_sleep_exit_flag)
//			{
//				global_15s_sleep_exit_flag = false;
//				return;
//			}
//            app_send_wake_info_delay();
        }
        if(keyboard_enable_flag)  // 键盘是否关闭
        {
           
		app_key_write_to_one_wire_buf(&key_value_queue,alls); //分析组合按键，组合按键，多媒体按键
            
        }
    }
}

/**
 * @brief : 改变键状态
 * @param : button 按键
 * @param : f_btn_down 用于判断键按下，还是键释放
 * @return uint8  0(不需要发送)  1(需要发送)  2(需要判断发送)
 */
uint8_t app_key_tick_change(Button_Queue_typedef *q, uint8_t i, bool f_btn_down)
{
    uint8_t status = 0;

    if(f_btn_down)
    {
        if(q->key_btn[i].press_tick < 0x7fff)
        {
            q->key_btn[i].press_tick ++;
        }
        q->key_btn[i].release_tick = 0;
    }else
    {
        if(q->key_btn[i].release_tick < 0x7fff)
        {
            q->key_btn[i].release_tick ++;
        }
        q->key_btn[i].press_tick = 0;
    }

    if((q->key_btn[i].release_tick == 0) && (q->key_btn[i].press_tick == 2) && (q->key_btn[i].value != 0xff))
    {
        if(q->key_btn[i].state == BTN_UP)
        {   // 首次键按下，需要发送键值
            q->key_btn[i].state = BTN_DOWN;
            status = 1;
        }
    }

    if((q->key_btn[i].press_tick == 0) && (q->key_btn[i].release_tick == 2) && (q->key_btn[i].value != 0xff))
    {
        if(q->key_btn[i].state == BTN_DOWN)
        {    // 首次键释放，需要发送键值
            q->key_btn[i].state = BTN_UP;
            status = 1;
        }
    }
    //-------------------------------------------------------------
    //根据需求再次发送键值
    if(q->key_btn[i].press_tick == 8)
    {
        if((q->key_btn[i].release_tick == 0)  && (q->key_btn[i].value != 0xff))
        {  
            // 键按下30mS时，再次发送键值 (9-3)*5=30mS
            if (q->key_btn[i].state == BTN_DOWN)
            {   
                status = 2;
            }
        }
    }
    if(q->key_btn[i].release_tick == 8) 
    {
        if((q->key_btn[i].press_tick == 0)  && (q->key_btn[i].value != 0xff))
        {  
            // 键释放30mS时，再次发送键值 (9-3)*5=30mS
            if (q->key_btn[i].state == BTN_UP)
            {
                q->key_btn[i].state = BTN_UP;
                status = 2; 
            }
        }
    }
    return status;
}

/**
 * @brief : 有多键按下时，将所有Tick同步到最小值
 * @return
 */
void app_key_all_tick_sync(void)
{
    uint16_t i,min_press_tick;

    min_press_tick = 0x7fff;
    for(i=0;i<KEY_BOTTON_MAX_NUM;i++)
    {
        if((kb_btn[i].release_tick == 0) && (kb_btn[i].press_tick > 3)  && (kb_btn[i].value != 0xff))
        {
            if(kb_btn[i].press_tick < min_press_tick)
            {
                min_press_tick = kb_btn[i].press_tick;
            }
        }
    }

    for(i=0;i<KEY_BOTTON_MAX_NUM;i++)
    {
        if((kb_btn[i].release_tick == 0) && (kb_btn[i].press_tick > 3)  && (kb_btn[i].value != 0xff))
        {
            if(kb_btn[i].press_tick > min_press_tick)
            {
                kb_btn[i].press_tick =  min_press_tick;
            }
        }
    }
}


/**
 * @brief 按键发送确认
 * 
 * @param status 状态
 * @return true 发送
 * @return false 不发送
 */
bool app_key_repeat_send(uint8_t status)
{
    bool ret = false;
    if(status == 1)
    { // 确定要发
        global_key_rec_ack_flag = 0;
        ret = true;
    }
    else if(status == 2)
    {  // 选择要发
//        if(global_key_rec_ack_flag != 0x00)
//            return ret;
//        global_key_rec_ack_flag = 0x01;    
//        ret = true;
		  return ret;
    }
    return ret;
}

/**
 * @brief 多媒体按键发送确认
 * 
 * @param status 状态
 * @return true 发送
 * @return false 不发送
 */
bool app_media_repeat_send(uint8_t status)
{
    bool ret = false;
    if(status == 1)
    {// 确定要发
        global_media_rec_ack_flag = 0;
        ret = true;
    }
    else if(status == 2)
    {// 选择要发
        if(global_media_rec_ack_flag != 0x00)
            return ret;
        global_media_rec_ack_flag = 0x01;
        ret = true;
    }
    return ret;
}

/**
 * @brief 队列按键按下状态
 * 
 * @param q 队列
 * @param i 序号
 * @return true 按下
 * @return false 抬起
 */
bool app_key_have_press_status(Button_Queue_typedef *q , uint8_t i)
{
    bool f_press = false;
    uint8_t mask = 0;
    mask = (uint8_t)0x80 >> (q->key_btn[i].pos_col);
    if(key_scan_value[q->key_btn[i].pos_row] & mask)
    {
        f_press = true;
    }
    return f_press;
}

//--------------------------------------------------------------------------------------------//
//----------------------------------------按键扫描相关-----------------------------------------//
//--------------------------------------------------------------------------------------------//
/**
 * @brief 将检测到的按键写入队列
 * 
 * @param key_botton_nnumber 按键数量
 * @return uint8_t 返回按键实际数量
 */
void app_key_get_botton_to_queue(uint8_t key_botton_nnumber)
{
    uint8_t mask = 0, i, j;

    for(i = 0; i < KEY_ROW_NUMBER; i++)
    {
        for(j = 0; j < KEY_COLUME_NUMBER; j++)
        {
            mask = (uint8_t)0x80 >> j;
            if(mask & key_scan_value[i])
            {
//				printf("i %d j %d\n",i,j);
                if(app_key_cheak_botton(&key_value_queue,(j + i * KEY_COLUME_NUMBER)))
                {
                    app_key_add_key_queue_write(&key_value_queue,(j + i * KEY_COLUME_NUMBER));
                }
            }
        }
    }
}

/**
 * @brief ：按键扫描函数，定时调用
 * 
 * @param
 * @return uint8_t 有几个键按下
 */
uint8_t app_key_scan(void)
{
	uint8_t scan_result;
	static uint8_t last_scan_result=0;
	static uint8_t	flag_count=0;

	scan_result = app_read_colume_in();
	flag_count++;
	if(last_scan_result!=scan_result)
	{
	last_scan_result=scan_result;
	flag_count=0;

	}
	if((flag_count>3) && !scan_result)
	{
	flag_count=0X3F;
	 return 0;

	}
    uint32_t num = 0;
    uint8_t i,j;
    app_key_all_colume_input_pull_up();
    app_key_all_row_input_pull_up();
    for(i=0;i<KEY_ROW_NUMBER;i++)
    {
        if(key_pin_row_tab[i] != 0xff)
        {
//			csi_pin_set_low(global_key_pin_row_buf[i]);
            app_key_row_out_low(key_pin_row_tab[i]);
            udelay(15);
            key_scan_value[i] = app_read_colume_in();
//			printf("----value-%d",key_scan_value[i]);
//			csi_pin_set_high(global_key_pin_row_buf[i]);
           app_key_io_input_pull_up(key_pin_row_tab[i]);
            j = key_scan_value[i];          //判断哪一列被按下
//			printf("---%d",j);
            while(j) 
            {
                j = j & (j - 1);
                num ++;             //判断一列(j)中有几个按键被按下
            }               
        }
        else
        {
            key_scan_value[i] = 0;
        }
    }
    return num;
}

/**
 * @brief ：读取一行扫描值
 * 
 * @param
 * @return uint32_t 扫描值
 */
uint8_t app_read_colume_in(void)
{
    uint8_t get_key = 0;
    for(uint32_t i = 0 ; i < KEY_COLUME_NUMBER ; i++)
    {
        get_key <<= 1;
        if(csi_pin_read(key_pin_colume_tab[i]) == 0)
        {
            get_key |= 0x01;
        }
    }
    return get_key;
}

/**
 * @brief ：计算有几个BIT置位
 * 
 * @param
 * @return uint8_t BIT数
 */
uint8_t app_key_bit_num(uint8_t val)
{
    uint8_t i, num = 0, mask;
    for(i = 0; i < KEY_COLUME_NUMBER; i++)
    {
        mask = (uint8_t)1<<i;
        if(mask & val)
        {
            num ++;
        }
    }
    return num;
}

/**
 * @brief ：判断两个扫描数据中是否有鬼键
 * 
 * @param
 * @return uint8_t 鬼键的位置
 */
uint32_t app_key_ghost_bits(uint32_t va,uint32_t vb)
{
    uint8_t i, num = 0, mask, ghost_bits = 0;
    for(i = 0; i < KEY_COLUME_NUMBER; i++)
    {
        mask = (uint8_t)1<<i;
        if(((mask & va) == (mask & vb)) && ((mask & va)>0))
        {
            num ++;
            ghost_bits |= mask;
        }
    }
    if(num >= 2)
    {
        return ghost_bits;
        
    }else
    {
        return 0;
    }
}

/**
 * @brief : 将需要发送的键值写入单总线缓中
 * @param : status(1:确定要发)  2(选择要发)
 * @return 
 */
void app_key_write_to_one_wire_buf(Button_Queue_typedef *q,uint8_t status)
{
       uint8_t ctrl_value    = 0;    //控制按键
    uint8_t scan_key_num  = 0;    //除控制按键外的按键个数
    uint8_t key_value[6]  = {0};
    uint8_t key_value_buf[6]  = {0};
    uint16_t key_media_value_par = 0;
    uint16_t key_media_value = 0;
    uint16_t key_media_value1 = 0;
    uint16_t i; 
	uint8_t fn_flag    = 0;
    ENUM_KEY_TYPE key_type_cur = KEY_TYPE_FREE; // 释放键
    ENUM_KEY_TYPE key_media_type_cur = KEY_TYPE_FREE; // 释放键
    //--------------------------------------------------
    // 分析键值
    for(i = 0; i < KEY_BOTTON_MAX_NUM; i++)
    {
        if((q->key_btn[i].state == BTN_DOWN) && (q->key_btn[i].value != 0xff))
        {
            // LeftCtrl(0xE0),LeftShift,LeftAlt,LeftGui(0xE3)
            // RightCtrl(0xE4),RightShift,RightAlt,RightGui(0xE7)
            if((q->key_btn[i].value >= 0xE0) && (q->key_btn[i].value <= 0xE7))
            {
                ctrl_value |= (1 << (q->key_btn[i].value-0xE0));
	//if (ctrl_value == (1 << (KB_Win - 0xE0)) && scan_key_num == 1)
	//{
		//win_flag = 0;
	//}

            }else
            {

				if (q->key_btn[i].value == T_FN ) //&& !factory_enter_flag   处理Fn
				{
					fn_flag = 1;
						 if (!pad_lcd_state) // 熄屏状态下，加入键值
							{
								key_value[scan_key_num++] = q->key_btn[i].value;
							}
						else if (factory_enter_flag) // 工厂测试模式下也加入键值
							{
								key_value[scan_key_num++] = q->key_btn[i].value;
							}
								// 其余情况不加入 FN 键值，仅标记 fn_flag
//						if (!pad_lcd_state) 
//						{
//								key_value[scan_key_num++] = q->key_btn[i].value;
//							one_wire_bus_app_send_keyboard(0, key_value, 1);  // 立即发送
//							return;  // 跳过后续处理
//						}
				}else
                if(scan_key_num < 6)
                {
//					if(q->key_btn[i].value==KB_xiegang && uk_flag)
//					{
//						key_value[scan_key_num++] = KB_K42;
//					}else
//					{
//						key_value[scan_key_num++] = q->key_btn[i].value;     //key_value[scan_key_num++] = q->key_btn[i].value; 键值序列加一
//					}
					key_value[scan_key_num++] = q->key_btn[i].value;     //key_value[scan_key_num++] = q->key_btn[i].value; 键值序列加一

                }
            }

            key_type_cur = KEY_TYPE_GENE; // 有键按下
        }
    }
	//处理组合键
	if(ctrl_value == (1 << (KB_Win - 0xE0)) && key_value[0]==KB_Up && scan_key_num == 1)
	{
		ctrl_value = 0;
		win_flag=1;
		memset(key_value, 0, sizeof(key_value));
		key_value[0] = 0x4b;
	}else if(ctrl_value == (1 << (KB_Win - 0xE0)) && key_value[0]==KB_Down && scan_key_num == 1)
	{
		ctrl_value = 0;
		win_flag=1;
		memset(key_value, 0, sizeof(key_value));
		key_value[0] = 0x4e;
	}else if(ctrl_value == (1 << (KB_Win - 0xE0)) && key_value[0]==KB_Left && scan_key_num == 1)
	{
		ctrl_value = 0;
		win_flag=1;
		memset(key_value, 0, sizeof(key_value));
		key_value[0] = 0x4a;
	}else if(ctrl_value ==(1 << (KB_Win - 0xE0)) && key_value[0]==KB_Right && scan_key_num == 1)//if(（ctrl_value & (1 << (KB_Win - 0xE0))）==(1 << (KB_Win - 0xE0)） && key_value[0]==KB_Right && scan_key_num == 1)
	{
		ctrl_value = 0;
		win_flag=1;
		memset(key_value, 0, sizeof(key_value));
		key_value[0] = 0x4d;
	}
	// ⬇️ 新增：Shift + Esc -> ~（KB_dunhao）
	else if (((ctrl_value & (1 << (KB_LShift - 0xE0))) || (ctrl_value & (1 << (KB_RShift - 0xE0))))&& key_value[0] == KB_Esc && scan_key_num == 1)
	{
		memset(key_value, 0, sizeof(key_value));
		key_value[0] = KB_dunhao;  // 0x35 表示 ~ 键
    // ctrl_value &= ~((1 << (KB_LShift - 0xE0)) | (1 << (KB_RShift - 0xE0))); // 可选：取消 Shift 修饰
	}else if(key_value[0]==KB_F11 && scan_key_num == 1)
	{
		ctrl_value |= (1 << (KB_LCtrl-0xE0));
		memset(key_value, 0, sizeof(key_value));
		key_value[0] = KB_P;
//		close_idet = 1;
	}else if(ctrl_value !=(1 << (KB_Win - 0xE0))){
		win_flag=0;
	}
	
	if(win_flag == 1)
	{
		ctrl_value &= ~(1 << (KB_Win - 0xE0));
	}


	
//    // printf("key 1: ");
    // console_log_num_byte((uint8_t *)&key_value[0],6);
    //-------------------------------------------------
    uint8_t media_flag = 0;
//	static uint8_t key_sent = 0;  // 用于标记当前按键是否已发送
	bool shield = true;
    //--------------------------------------------------
    //多媒体按键
if(scan_key_num != 0x00)
{
	if (!pad_lcd_state) // 屏幕没亮
    {
        memset(key_value, 0, sizeof(key_value));
        key_value[0] = 0x40;  // 发唤醒指令
    }
    uint8_t num = scan_key_num;
    for(uint8_t u = 0; u < num; u++)
    {

        if(fn_flag)
        {
            switch(key_value[u])
            {
                case KB_Esc:  //esc
                    key_value[u] = KB_dunhao;
                    break;
                case KB_1: //截屏
                    memset(key_value, 0, sizeof(key_value));
                    key_value[0] = KB_F1;
                    break;
                case KB_2: //录屏
                    media_flag = 1;
                    key_media_value_par = 0x181;
                    break;
                //case KB_3: //禁用触摸板
                //    media_flag = 1;
                //    key_media_value_par = 0x18f;
                //    break;
                case KB_4: //静音
                    key_value[u] = KB_F4;
                    break;
                case KB_5: //音量减
                    key_value[u] = KB_F5;
                    break;
                case KB_6: //音量加
                    key_value[u] = KB_F6;
                    break;
                case KB_7: //禁用麦克风
                    key_value[u] = KB_F7;
                    break;
                case KB_8: //摄像头禁止开启
                    media_flag = 1;
                    key_media_value_par = 0x19f;
                    break;
                case KB_9: //搜索键
                    media_flag = 1;
                    key_media_value_par = 0x2c7;
                    break;
                case KB_0: //备忘录
                    media_flag = 1;
                    key_media_value_par = 0x2c8;
                    break;
                case KB_jianhao: //APP1
                    media_flag = 1;
                    key_media_value_par = 0x2c9;
                    break;
                case KB_denghao: //APP2
                    media_flag = 1;
                    key_media_value_par = 0x2ca;
                    break;
				case KB_Voice: //录音键
                    media_flag = 1;
                    key_media_value_par = 0x79;
                    break;	
                default:
                    break;
            }
        }
        else
        {
//			if(pad_lcd_state)
//		{
				
			
            switch(key_value[u])
            {
                case KB_Esc:  //esc
                    media_flag = 1;
                    key_media_value_par = 0x224;
                    break;
                case KB_F2: //录屏
                    media_flag = 1;
                    key_media_value_par = 0x181;
                    break;
                case KB_F3: //禁用触摸板
                    media_flag = 1;
                    key_media_value_par = 0x18f;
                    break;
                case KB_F8: //摄像头禁止开启
                    media_flag = 1;
                    key_media_value_par = 0x19f;
                    break;
                case KB_F9: //app3
                    media_flag = 1;
                    key_media_value_par = 0x185;
                    break;
                case KB_F10: //备忘录
                    media_flag = 1;
                    key_media_value_par = 0x2c8;
                    break;
                case KB_F12: //APP1
                    media_flag = 1;
                    key_media_value_par = 0x2c9;
                    break;
                case KB_F13: //APP2
                    media_flag = 1;
                    key_media_value_par = 0x2ca;
                    break;
                case KB_Search: //搜索键
                    media_flag = 1;
                    key_media_value_par = 0x2c7;
                    break;
                case KB_Voice: //录音键
                    media_flag = 1;
                    key_media_value_par = 0x79;
                    break;
                default:
                    break;
            }
//			}else{
//				memset(key_value, 0, sizeof(key_value));
//				key_value[0] = 0x40;
//			}
        }

        if(key_media_value_par != 0x00)
        {
            scan_key_num--;
            key_value[u] = 0x00;
            if(key_media_value == 0x00)
            {
                key_media_value = key_media_value_par;
            }
            else if(key_media_value1 == 0x00)
            {
                key_media_value1 = key_media_value_par;
            }
            key_media_value_par = 0x00;
        }
    }

    uint8_t key_value_bum = 0;
    for(i = 0; i < 6; i++)
    {
        if(key_value[i] == 0x00)
            continue;
        key_value_buf[key_value_bum++] = key_value[i];
    }
    memcpy((uint8_t *)&key_value[0], key_value_buf, 6);
}
    if(media_flag == 1)
    {        
        key_media_type_cur = KEY_TYPE_MEDIA; // 有多媒体键按下
    }
    if((key_value[0] == 0x00) && (ctrl_value == 0x00))
    {
        key_type_cur = KEY_TYPE_FREE; 
    }
    //--------------------------------------------------
    bool rec_ack_f;
    if((media_flag == 0x00))
    {   // 释放键
        if(key_madia_type_back == KEY_TYPE_MEDIA)
        {
//            app_lowpower_disable_tp_set();
            if(Waiting_sleep)
            {
                key_madia_type_back = KEY_TYPE_FREE;
                Waiting_sleep = 0x00;
                return;
            }
            bool ret =one_wire_bus_app_send_media_key(0,0);
            if(ret)
            key_madia_type_back = KEY_TYPE_FREE;
        }
    }
    if((scan_key_num == 0) && (ctrl_value == 0))
    {   // 释放键
        if(key_type_back == KEY_TYPE_GENE)
        {
//            app_lowpower_disable_tp_set();
            if(Waiting_sleep)
            {
                key_type_back = KEY_TYPE_FREE;
                Waiting_sleep = 0x00;
                return;
            }
			bool ret = one_wire_bus_app_send_keyboard(ctrl_value,(uint8_t *)&key_value[0],scan_key_num);
			
			if(ret)
				key_type_back = KEY_TYPE_FREE;
        }
    }
    if((media_flag != 0x00)&&(key_media_type_cur == KEY_TYPE_MEDIA))
    {
        if(key_madia_type_back == KEY_TYPE_FREE)
        {
            rec_ack_f = app_media_repeat_send(status);
            if(rec_ack_f)
            {
                one_wire_bus_app_send_media_key(key_media_value,key_media_value1);
//                app_lowpower_key_up__disable_tp();
            }
            key_madia_type_back = KEY_TYPE_MEDIA;
        }
    }

    if(((scan_key_num != 0) && (key_type_cur == KEY_TYPE_GENE)) ||
            ((ctrl_value != 0) && (key_type_cur == KEY_TYPE_GENE)))
    {
        rec_ack_f = app_key_repeat_send(status);

		  if(rec_ack_f&&shield)
          {
            one_wire_bus_app_send_keyboard(ctrl_value,(uint8_t *)&key_value[0],scan_key_num);
//            app_lowpower_key_up__disable_tp();
           }
	
        key_type_back = KEY_TYPE_GENE;
    }
}
// uint32_t num = 0;
/**
 * @brief ：根据按键扫描结果，判断是否有鬼键
 * 
 * @param  key_num 检测到的按键数量
 * @return uint8_t 有几个键按下
 */
uint8_t app_key_check_ghost(Button_Queue_typedef *q, uint8_t number_key_button)
{
    uint16_t i,j,k,v;
    uint8_t real_key_num = 0,key_ghost_line_num,have_ghost_key;

    real_key_num = number_key_button;
    have_ghost_key = 0x00;
    key_ghost_line_num = 0x00;
    //---------------------------------------------------------------------
    // 判断是否有鬼键
    for(i = 0; i < MAX_GHOST_LINE_NEM; i ++)
    {
        key_ghost_value[i][0] = 0x00;  // 鬼键键值
        key_ghost_value[i][1] = 0x00;  // 鬼键行号
        key_ghost_value[i][2] = 0x00;  // 鬼键位置
    }
    if((real_key_num >= 4) && (real_key_num < 6))
    {
        /*
        * 一根扫描线上有两个以上键按下，记录到key_ghost_value数组中
        * 最多记录三组，因每根扫描线上有两个键，所以最多记录6个键
        *   key_ghost_value[x][0] ：记录对应扫描线
        *   key_ghost_value[x][1] ：记录相应扫描值
        *   key_ghost_value[x][2] : 记录鬼键位置
        */
        for(i = 0; i < KEY_ROW_NUMBER; i ++)
        {
            if(key_scan_value[i] == 0x00)
                continue;
            // 一根扫描线上有键按下
            if(app_key_bit_num(key_scan_value[i]) < 2)
                continue;
            // 一根扫描线上有两个以上键按下，记录到数据中
            for(j = 0; j < MAX_GHOST_LINE_NEM; j ++)
            {
                if(key_ghost_value[j][1] == 0x00)
                {
                    key_ghost_value[j][0] = i;                  // 记录扫描线
                    key_ghost_value[j][1] = key_scan_value[i];  // 记录扫描值
                    key_ghost_line_num ++;                      // 记录总共有多少根
                    break;
                }
            }
        }
        //--------------------------------------------------------------------------
        // 分析并记录鬼键位置
        if(key_ghost_line_num >= 2)
        {   
            //记录鬼键的位置
            key_ghost_value[0][2] = app_key_ghost_bits(key_ghost_value[0][1],key_ghost_value[1][1]);
            key_ghost_value[1][2] = app_key_ghost_bits(key_ghost_value[1][1],key_ghost_value[2][1]);
            key_ghost_value[2][2] = app_key_ghost_bits(key_ghost_value[2][1],key_ghost_value[0][1]);
        }
        if((key_ghost_value[0][2] > 0)  || (key_ghost_value[1][2] > 0) || (key_ghost_value[2][2] > 0))
        {   
            // 其中任意两根上有鬼键
            have_ghost_key = 1;
        }
    }else
    {
        have_ghost_key = 0;
    }
    if(real_key_num >= 6) 
    {
        for(v = 0; v < KEY_ROW_NUMBER; v ++)
        {
            key_scan_value[v] = 0;
        }
    }
    //------------------------------------------------------------------------
    //找出表中鬼键位置
    if(!have_ghost_key)
        return real_key_num;
    for(i = 0; i < MAX_BIT_GHOST_NUM; i++)
    {
        btn_ghost_index[i] = 0x00;
    }
    for(k = 0; k < MAX_GHOST_LINE_NEM; k++)
    {
        if(key_ghost_value[k][2] == 0x00)
            continue;
        /*
        * 定位出鬼键的四个键位置
        * 根据key_ghost_value[x][2],算出当前扫描线的鬼键位置，和下一根扫描线的鬼键位置
        * 最多6个键
        */
        uint8_t mask;
        for(i = 0; i < KEY_COLUME_NUMBER; i ++)
        {
            mask = (uint8_t)0x80 >> i;

            if(mask & key_ghost_value[k][2])
            {
                for(j = 0; j < 3; j++)
                {
                    if(btn_ghost_index[j] == 0)
                    {
                        btn_ghost_index[j] = i + key_ghost_value[k][0]*8;//用来记录对应的键值在键值表中的位置
                        break;
                    }
                }
            }
            if(mask & key_ghost_value[k][2])
            {
                uint8_t next;
                next = k+1;
                if(next >= MAX_GHOST_LINE_NEM)
                {
                    next = 0;
                }
                for(j = 0; j < 3; j++)
                {
                    if(btn_ghost_index[j + 3] == 0)
                    {
                        btn_ghost_index[j + 3] = i + key_ghost_value[next][0]*8;
                        break;
                    }
                }
            }
        }
        //------------------------------------------------------------------------
        //剔除鬼键
        for(uint8_t n = 0; n < MAX_BIT_GHOST_NUM; n ++)
        {
            if(btn_ghost_index[n] == 0x00)
                continue;
            for(uint8_t z = 0; z < 12; z++)
            {
                if((q->key_btn[z].key_location == btn_ghost_index[n]))
                {
                    if(q->key_btn[z].press_tick <= 1)
                    {
                        uint8_t row,col;
                        uint8_t val;
                        row = (q->key_btn[z].key_location) / 8;
                        col = (q->key_btn[z].key_location) % 8;
                        val = ~((uint8_t)0x80 >> col);
                        key_scan_value[row] &= val;
                        if(real_key_num)
                        {
                            real_key_num --;
                        }
                        // num ++;
                        // printf("num = %d\n",num);
                        // printf("real_key_num = %d\n",real_key_num);
                        // printf("row = %d , col = %d\n",row,col);
                        // printf("\n");
                    }
                }
            }
        }

    }
    // printf("real_key_num1 = %d\n",real_key_num);
    // printf("\n");
    return real_key_num;
}
//--------------------------------------------------------------------------------------------//
//--------------------------------------按键扫描GPIO设置---------------------------------------//
//--------------------------------------------------------------------------------------------//
/**
 * @brief ：将row io设置为输入,上拉
 * 
 * @param
 * @return
 */
void app_key_io_input_pull_up(uint8_t pin)
{
    csp_gpio_t *ptGpioBase;
    uint8_t index;
    uint32_t *ptPinInfo;

    ptPinInfo = chip_get_pin_name_addr(pin);
    ptGpioBase = (csp_gpio_t *)ptPinInfo[0];						//pin addr
    index = (pin_name_e)ptPinInfo[1];							//pin
    //--------------------------------------------
    // set pin input
    if(index < 8)
    {
        ptGpioBase->CONLR =(ptGpioBase->CONLR & ~(0xF << 4*index)) | (GPIO_DIR_INPUT << 4*index);
    }
    else
    {
        ptGpioBase->CONHR =(ptGpioBase->CONHR & ~(0xF << 4*(index-8))) | (GPIO_DIR_INPUT << 4*(index-8));
    }
    //--------------------------------------------
    // set pull up
    ptGpioBase->PUDR  = ((ptGpioBase->PUDR) & ~(0x03 << (index*2))) | (0x01 << (index*2));
    //--------------------------------------------
}

/**
 * @brief ：指定row io输出低电平
 * 
 * @param pin:引脚
 * @return
 */
void app_key_row_out_low(uint8_t pin)
{
    csp_gpio_t *ptGpioBase = NULL;
    uint8_t index;
    uint32_t *ptPinInfo;

    ptPinInfo = chip_get_pin_name_addr(pin);
    ptGpioBase = (csp_gpio_t *)ptPinInfo[0];		//pin addr
    index = (pin_name_e)ptPinInfo[1];				//pin
    //--------------------------------------------
    // set pin output
    if(index < 8)
    {
        ptGpioBase->CONLR =(ptGpioBase->CONLR & ~(0xF << 4*index)) | (GPIO_DIR_OUTPUT << 4*index);
    }
    else
    {
        ptGpioBase->CONHR =(ptGpioBase->CONHR & ~(0xF << 4*(index-8))) | (GPIO_DIR_OUTPUT << 4*(index-8));
    }
    ptGpioBase->WODR = ptGpioBase->ODSR & (~(0x1 << index));
    ptGpioBase->PUDR = ((ptGpioBase->PUDR) & ~(0x03 << (index*2)));
}

/**
 * @brief ：将所有的row io设置为输入,上拉
 * 
 * @param
 * @return
 */
void app_key_all_row_input_pull_up(void)
{
    uint8_t k;
    for(k=0;k<KEY_ROW_NUMBER;k++)
    {
        if(key_pin_row_tab[k] != 0xff)
        {
            app_key_io_input_pull_up(key_pin_row_tab[k]);
        }
    }
}

/**
 * @brief ：将所有的col io设置为输入,上拉
 * 
 * @param
 * @return
 */
void app_key_all_colume_input_pull_up(void)
{
    uint8_t i;
    for(i=0;i<KEY_COLUME_NUMBER;i++)
    {
        if(key_pin_colume_tab[i] != 0xff)
        {
            app_key_io_input_pull_up(key_pin_colume_tab[i]);
        }
    }
}

/**
 * @brief 设置row 输出低电平
 * 
 */
void app_key_all_row_out_low(void)
{
    uint8_t k;
    for(k=0;k<KEY_ROW_NUMBER;k++)
    {
        if(key_pin_row_tab[k] != 0xff)
        {    
            app_key_row_out_low(key_pin_row_tab[k]);
        }
    }
}

//--------------------------------------------------------------------------------------------//
//-----------------------------------------按键队列--------------------------------------------//
//--------------------------------------------------------------------------------------------//
/**
 * @brief 写队列
 * 
 * @param q 队列指针
 * @param location_botton 按键绝对位置
 * @return true 写入成功
 * @return false 写入失败
 */
bool app_key_add_key_queue_write(Button_Queue_typedef *q,uint8_t location_botton)
{
    uint8_t cover_key,row_buf,col_buf;
    uint16_t release_max = 0;
    uint8_t need_cover = 0;
    Button_Typedef * key_botton = NULL;
//	printf("location_botton %x\n",location_botton);
    if(location_botton > TOTAL_BUTTON_NUMBER)
    {
        return false;
    }

    row_buf = location_botton / KEY_COLUME_NUMBER;
    col_buf = location_botton % KEY_COLUME_NUMBER;
	
//	printf("row_buf %d col_buf %d\n",row_buf,col_buf);
    if (key_map[row_buf][col_buf] == 0xff){
        return false;
    }
//	printf("key %x\n",key_map[row_buf][col_buf]);
    //查找出releas最久的键
    for (uint8_t c = 0; c < 12 ; c++){
        if ((q->key_btn[c].release_tick > release_max) && (q->key_btn[c].release_tick != 0x7fff) && (q->key_btn[c].release_tick != 0)){
            release_max = q->key_btn[c].release_tick;
            cover_key = c;
            need_cover = 1;
        }
    }
    //把头拷贝到release最久的键的位置
    if (need_cover == 1){
        memcpy(&(q->key_btn[cover_key]),&(q->key_btn[q->head]),sizeof(Button_Typedef));
    }

    if(q->queue_existing_len >= KEY_BOTTON_MAX_NUM)
    {
        q->head = (q->head + 1)%KEY_BOTTON_MAX_NUM;
        q->queue_existing_len --;
    }

    key_botton = (Button_Typedef *)&(q->key_btn[q->tail]);
    key_botton->key_location = location_botton;
    key_botton->pos_row = (key_botton->key_location) / KEY_COLUME_NUMBER;
    key_botton->pos_col = (key_botton->key_location) % KEY_COLUME_NUMBER;
    key_botton->value = key_map[key_botton->pos_row][key_botton->pos_col];
    key_botton->press_tick = 0;
    key_botton->release_tick = 0x7fff;
    key_botton->state = BTN_UP;
    
    q->tail = (q->tail + 1)%KEY_BOTTON_MAX_NUM;
    q->queue_existing_len ++;

    return true;
}

/**
 * @brief 创建队列
 * 
 * @param q 队列指针
 */
void app_key_create_queue(Button_Queue_typedef *q)
{
    memset((Button_Typedef *)&kb_btn[0],0,sizeof(kb_btn));
    q->key_btn = (Button_Typedef *)&kb_btn[0];
    q->head = 0x00;
    q->tail = 0x00;
    q->queue_existing_len = 0x00;
}

/**
 * @brief 检查按键是否重复
 * 
 * @param q 队列指针
 * @param location_botton 按键绝对位置
 * @return true 重复
 * @return false 没有重复
 */
bool app_key_cheak_botton(Button_Queue_typedef *q ,uint8_t location_botton)
{
    for(uint8_t i = 0; i < KEY_BOTTON_MAX_NUM; i++)
    {
        if(kb_btn[i].key_location == location_botton)
        {
            return false;
        }
    }
    return true;
}

uint8_t app_key_cheak_release_status(Button_Queue_typedef *q)
{
    Button_Typedef * key_botton = NULL;
    uint8_t number_key = 0;
    for(uint8_t i = 0; i < KEY_BOTTON_MAX_NUM; i++)
    {
        key_botton = (Button_Typedef *)&(q->key_btn[i]);
        if(key_botton->state == BTN_DOWN)
        {
            number_key ++;
        }
    }
    return number_key;
}

//--------------------------------------------------------------------------------------------//
//-----------------------------------------休眠唤醒--------------------------------------------//
//--------------------------------------------------------------------------------------------//
/**
 * @brief 产测进入
 * 
 * @param on true 进入 ； false 退出
 */
void app_enter_factor_mode(bool on)
{
    global_key_timer_flag = 0x00;
    if(on)
    {
        global_key_test_status = 0x00;
    }else
    {
        app_key_init(true);
        global_key_test_status = 0x01;
        global_factory_enter_on = false;
    }
}

/**
 * @brief 设置中断唤醒
 * 
 */
void app_key_set_wakeup_irq(void)
{
    uint8_t index;
    uint32_t *ptPinInfo;

    for(uint8_t i = 0; i < KEY_COLUME_NUMBER; i++)
    {
        ptPinInfo = chip_get_pin_name_addr(key_pin_colume_tab[i]);
        index = (pin_name_e)ptPinInfo[1];
        csi_pin_irq_mode(key_pin_colume_tab[i],(csi_exi_grp_e)index, GPIO_IRQ_FALLING_EDGE);  //下降沿产生中断，选择中断组11
        csi_pin_irq_enable(key_pin_colume_tab[i],(csi_exi_grp_e)index, ENABLE);   
    }
    csi_vic_set_wakeup_irq(EXI3_IRQ_NUM);  //EXI GROUP4~9
    csi_vic_set_wakeup_irq(EXI4_IRQ_NUM);  //EXI GROUP10~15  
    csi_vic_set_wakeup_irq(EXI2_IRQ_NUM);  //EXI GROUP2~3/GROUP18~19
}

/**
 * @brief 关闭io中断
 * 
 */
void app_key_wake_exi_disable(void)
{
    uint8_t index;
    uint32_t *ptPinInfo;

    for(uint8_t i = 0; i < KEY_COLUME_NUMBER; i++)
    {
        ptPinInfo = chip_get_pin_name_addr(key_pin_colume_tab[i]);
        index = (pin_name_e)ptPinInfo[1];
        csi_pin_irq_enable(key_pin_colume_tab[i],(csi_exi_grp_e)index, DISABLE);  //中断使能关闭
    }
    csi_vic_clear_wakeup_irq(EXI3_IRQ_NUM);  //EXI GROUP4~9
    csi_vic_clear_wakeup_irq(EXI4_IRQ_NUM);  //EXI GROUP10~15  
    csi_vic_clear_wakeup_irq(EXI2_IRQ_NUM);  //EXI GROUP2~3/GROUP18~19
}

/**
 * @brief led低功耗设置
 *  
 */
void app_key_led_lowpower_set(void)
{
    csi_pin_pull_mode(hardware[0].IO_name,GPIO_PULLDOWN);
    csi_pin_pull_mode(hardware[1].IO_name,GPIO_PULLDOWN);
    csi_pin_set_mux(hardware[0].IO_name,hardware[0].IO_mode_gpd);
    csi_pin_set_mux(hardware[1].IO_name,hardware[1].IO_mode_gpd);
}

void app_key_factory_io_sleep_set(void)
{
    uint8_t mode = 0;
    for (uint16_t i = 0; i < KEY_COLUME_NUMBER; i++)
    {
        csi_pin_set_mux(key_pin_colume_tab[i],(pin_func_e)mode);
    }
    for (uint16_t i = 0; i < KEY_ROW_NUMBER; i++)
    {
        csi_pin_set_mux(key_pin_row_tab[i],(pin_func_e)mode);
    }
}

/**
 * @brief 唤醒时键盘灯光控制
 * 
 * @param status LED status
 */
void app_led_ctrl(uint8_t status)
{
    app_key_led_set_mode(LED_CAPS, status&0x01);
    app_key_led_set_mode(LED_MIC, (status&0x02) >> 1);
}

/**
 * @brief 调试低功耗设置
 * 
 * @param on true 唤醒 false 休眠
 */
void app_key_low_power_sleep_set(bool on)
{
    if(on)
    {
        //退出中断唤醒
        app_key_wake_exi_disable();
        //按键初始化
        app_key_init(false);
        //控制灯光
		app_led_ctrl(keyboard_led_status);
    }else
    {
        if(pad_cover_state)
        {
            #if APP_DEBUG_POWER_ON_LOG_ENABLE
                printf("factory sleep\n");
            #endif
			app_key_wake_exi_disable();
            app_key_factory_io_sleep_set();
        }else
        {
            #if APP_DEBUG_POWER_ON_LOG_ENABLE
                // printf("key sleep\n");
            #endif
		  if(pad_cover_state)
		  {
			   //上拉row引脚
			  app_key_all_row_input_pull_up();
		  }else{
			  //拉低row引脚
			   app_key_all_row_out_low();
		  }
            //设置col引脚上拉输入
            app_key_all_colume_input_pull_up();
            //设置io中断唤醒
            app_key_set_wakeup_irq();
        }
        //设置led输出
        app_key_led_lowpower_set();
    }
}
